package top.xierongsheng.code.oss;

import com.aliyun.oss.OSS;
import com.aliyun.oss.OSSClientBuilder;
import com.aliyun.oss.model.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.multipart.MultipartFile;

import jakarta.annotation.PostConstruct;
import java.io.*;
import java.net.URL;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

@Component
public class OSSClientService {

    private static final Logger LOG = LoggerFactory.getLogger(OSSClientService.class);

    @Autowired
    private OSSConfig ossConfig;

    private static OSS ossClient;

    private static OSSClientService ossClientService;

    /**
     * 初始化
     *
     * @auther 谢荣生
     * @datetime 2021/1/6 16:30
     */
    @PostConstruct
    public void init() {
        ossClientService = this;
        ossClient = new OSSClientBuilder().build(ossClientService.ossConfig.getEndpoint(), ossClientService.ossConfig.getAccessKeyId(), ossClientService.ossConfig.getAccessKeySecret());
        List<String> refererList = new ArrayList<String>();
        // 添加Referer白名单。Referer参数支持通配符星号（*）和问号（？）。
        refererList.add("http://*.xierongsheng.top");
        refererList.add("https://*.xierongsheng.top");
        refererList.add("http://localhost");
        // 设置存储空间Referer列表。设为true表示Referer字段允许为空。
        BucketReferer br = new BucketReferer(true, refererList);
        //判断存储库是否存在不存在就创建它
        //正式库
        boolean regularExists = ossClient.doesBucketExist(ossClientService.ossConfig.getRegularData());
        //临时库
        boolean tempExists = ossClient.doesBucketExist(ossClientService.ossConfig.getTempData());
        if (!regularExists) {
            CreateBucketRequest createBucketRequest = new CreateBucketRequest(ossClientService.ossConfig.getRegularData());
            ossClient.createBucket(createBucketRequest);
            SetBucketTaggingRequest request = new SetBucketTaggingRequest(ossClientService.ossConfig.getRegularData());
            request.setTag("RegularData", "正式库");
            ossClient.setBucketTagging(request);
            //正式库访问权限为公共读
            ossClient.setBucketAcl(ossClientService.ossConfig.getRegularData(), CannedAccessControlList.PublicRead);
            //设置防盗链
            ossClient.setBucketReferer(ossClientService.ossConfig.getRegularData(), br);
        }
        if (!tempExists) {
            CreateBucketRequest createBucketRequest = new CreateBucketRequest(ossClientService.ossConfig.getTempData());
            ossClient.createBucket(createBucketRequest);
            SetBucketTaggingRequest request = new SetBucketTaggingRequest(ossClientService.ossConfig.getTempData());
            request.setTag("TempData", "临时库");
            ossClient.setBucketTagging(request);
            //临时库访问权限为公共读
            ossClient.setBucketAcl(ossClientService.ossConfig.getTempData(), CannedAccessControlList.PublicRead);
            //设置防盗链
            ossClient.setBucketReferer(ossClientService.ossConfig.getTempData(), br);
        }
    }

    /**
     * 销毁
     *
     * @auther 谢荣生
     * @datetime 2021/1/6 16:33
     */
    public static void destory() {
        ossClient.shutdown();
    }


    /**
     * 上传文件至临时库
     *
     * @param file
     * @return
     * @throws IOException
     */
    public static String uploadFileTemp(MultipartFile file) throws IOException {
        String originalFilename = file.getOriginalFilename();
        return  saveFile(originalFilename, file);
    }

    /**
     * 文件上传到临时存储库并返回其访问链接
     *
     * @param name 文件名
     * @param file 文件源
     * @return
     * @throws IOException
     */
    public static String saveFile(String name, MultipartFile file) throws IOException {
        PutObjectRequest putObjectRequest = new PutObjectRequest(ossClientService.ossConfig.getTempData(), name, file.getInputStream());
        ossClient.putObject(putObjectRequest);
        // 设置URL过期时间为1小时。
        Date expiration = new Date(new Date().getTime() + 3600 * 1000);
        // 生成以GET方法访问的签名URL，访客可以直接通过浏览器访问相关内容。
        URL url = ossClient.generatePresignedUrl(ossClientService.ossConfig.getTempData(), name, expiration);
        return getFileUrl(url);
    }


    /**
     * 文件移动正式库并返回其长效访问链接同时删除临时库相同文件
     *
     * @param url 临时存储库文件访问地址
     * @return
     * @throws IOException
     * @auther 谢荣生
     * @datetime 2021/3/1 11:25
     */
    public static String uploadFileRegular(String url){
        String name = url.substring(url.lastIndexOf('/') + 1);
        //判断文件是否存在
        boolean found = ossClient.doesObjectExist(ossClientService.ossConfig.getTempData(), name);
        System.out.print(found);
        if (!found) {
            return null;
        }
        //复制文件
        CopyObjectResult result = ossClient.copyObject(ossClientService.ossConfig.getTempData(), name, ossClientService.ossConfig.getRegularData(), name);
        //删除临时文件
        ossClient.deleteObject(ossClientService.ossConfig.getTempData(), name);
        // 设置URL过期时间为1小时。
        Date expiration = new Date(new Date().getTime() + 3600 * 1000);
        // 生成以GET方法访问的签名URL，访客可以直接通过浏览器访问相关内容。
        URL fileUrl = ossClient.generatePresignedUrl(ossClientService.ossConfig.getRegularData(), name, expiration);
        return getFileUrl(fileUrl);
    }


    /**
     * 获取文件软连接
     *
     * @param url
     * @return
     * @auther 谢荣生
     * @datetime 2021/3/1 11:23
     */
    public static String getFileUrl(URL url) {
        if (url != null) {
            String urlPath = url.toString();
            String[] split = urlPath.split("\\?");
            String imgUrl = split[0];
            StringBuilder sb = new StringBuilder(imgUrl);
            sb.insert(4, "s");
            return sb.toString();
        }
        return null;
    }
}
